package com.qiantu.phone.widget.btnview;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import com.qiantu.phone.R;
import com.qiantu.phone.app.AppApplication;

/**
 * 画虚线
 * Created by luzx on 2019/05/05.
 */
public class OneButtonView extends View {
    private static final int[] SELECTED_STATE_SET = {
            android.R.attr.state_selected
    };
    private static final int[] UNSELECTED_STATE_SET = {
            -android.R.attr.state_selected
    };

    private int strokeColor;
    private int pressedColor;
    private int strokeWidth;
    private int radius;
    private Paint paint;
    private RectF mRectF;
    private Drawable backgroundDrawable;
    private Drawable centerDrawable;
    private int centerDrawableWidth;
    private int centerDrawableHeight;
    private String centerText;
    private int centerTextSize;
    private ColorStateList centerTextColor;
    private TextPaint mTextPaint;
    private int shadowRadius1;
    private int shadowRadius2;
    private int shadowRadius3;
    private int shadowDy1;
    private int shadowDy2;
    private int shadowDy3;
    private int centerRadiusOffset;
    private boolean isPressed;
    private int addWidth;
    private Path mPath;
    private int deviceSolidBgColor;

    public OneButtonView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public OneButtonView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.OneButtonView);
        strokeColor = ta.getColor(R.styleable.OneButtonView_one_button_view_stroke_color, 0);
        pressedColor = ta.getColor(R.styleable.OneButtonView_one_button_view_pressed_color, AppApplication.getInstance().getThemeColor(R.attr.themeColor));
        strokeWidth = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_stroke_width, 1);
        radius = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_radius, 10);
        backgroundDrawable = ta.getDrawable(R.styleable.OneButtonView_one_button_view_background_drawable);
        centerDrawable = ta.getDrawable(R.styleable.OneButtonView_one_button_view_center_drawable);
        centerDrawableWidth = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_center_drawable_width, 0);
        centerDrawableHeight = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_center_drawable_height, 0);
        centerText = ta.getString(R.styleable.OneButtonView_one_button_view_center_text);
        centerTextSize = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_center_text_size, getResources().getDimensionPixelSize(R.dimen.dp_18));
        centerTextColor = ta.getColorStateList(R.styleable.OneButtonView_one_button_view_center_text_color);
        shadowRadius1 = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_shadow_radius1, getResources().getDimensionPixelSize(R.dimen.dp_52));
        shadowRadius2 = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_shadow_radius2, getResources().getDimensionPixelSize(R.dimen.dp_26));
        shadowRadius3 = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_shadow_radius3, getResources().getDimensionPixelSize(R.dimen.dp_13));
        shadowDy1 = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_shadow_dy1, getResources().getDimensionPixelSize(R.dimen.dp_26));
        shadowDy2 = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_shadow_dy2, getResources().getDimensionPixelSize(R.dimen.dp_11));
        shadowDy3 = ta.getDimensionPixelSize(R.styleable.OneButtonView_one_button_view_shadow_dy3, getResources().getDimensionPixelSize(R.dimen.dp_4));
        // 解析后释放资源
        ta.recycle();

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);

        mPath = new Path();
        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(centerTextSize);
        mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
        mRectF = new RectF();
        /*if(centerDrawable != null && centerDrawableWidth != 0 && centerDrawableHeight != 0){
            BitmapDrawable bd = (BitmapDrawable) centerDrawable;
            Bitmap newBmp = Bitmap.createScaledBitmap(bd.getBitmap(), centerDrawableWidth, centerDrawableHeight, true);
            centerDrawable = new BitmapDrawable(getResources(), newBmp);
        }*/
        centerRadiusOffset = getResources().getDimensionPixelSize(R.dimen.dp_4);
        addWidth = shadowRadius1 - strokeWidth;
        addWidth = addWidth < 0 ? 0 : addWidth;
        deviceSolidBgColor = AppApplication.getInstance().getThemeColor(R.attr.deviceSolidBgColor);
    }

    public void setText(String text) {
        this.centerText = text;
        invalidate();
    }

    public void setText(int text) {
        this.centerText = getResources().getString(text);
        invalidate();
    }

    public void setCenterTextSize(int centerTextSize) {
        this.centerTextSize = centerTextSize;
        mTextPaint.setTextSize(centerTextSize);
        invalidate();
    }

    public void setCenterTextColor(int resId) {
        this.centerTextColor = getResources().getColorStateList(resId);
        invalidate();
    }

    public void setStrokeColorColor(int startColor) {
        this.strokeColor = startColor;
    }

    public void setStrokeWidth(int strokeWidth) {
        this.strokeWidth = strokeWidth;
        paint.setStrokeWidth(strokeWidth);
    }

    public void setRadius(int radius) {
        this.radius = radius;
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if(addWidth > 0){
            int width = getMeasuredWidth() + addWidth * 2;
            int height = getMeasuredHeight() + addWidth * 2;
            setMeasuredDimension(width, height);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        paint.setStyle(Paint.Style.FILL);
        if (isSelected()) {
            if(backgroundDrawable != null){
                backgroundDrawable.setBounds(0, 0, getWidth(), getHeight());
                backgroundDrawable.draw(canvas);
            }else{
                drawCenter(canvas);
            }
        } else {
            drawCenter(canvas);
        }
        if(isPressed){
            paint.setColor(pressedColor);
            canvas.drawPath(mPath, paint);
        }
        if (centerDrawable != null) {
            if (isEnabled()) {
                centerDrawable.setAlpha(255);
            } else {
                centerDrawable.setAlpha(80);
            }
            if (centerDrawableWidth !=0 && centerDrawableHeight !=0){
                centerDrawable.setBounds((int) ((getWidth() - centerDrawableWidth) / 2f),
                        (int) ((getHeight() - centerDrawableHeight) / 2f),
                        (int) ((getWidth() + centerDrawableWidth) / 2f),
                        (int) ((getHeight() + centerDrawableHeight) / 2f));
            }else {
                centerDrawable.setBounds((int) ((getWidth() - centerDrawable.getIntrinsicWidth()) / 2f),
                        (int) ((getHeight() - centerDrawable.getIntrinsicHeight()) / 2f),
                        (int) ((getWidth() + centerDrawable.getIntrinsicWidth()) / 2f),
                        (int) ((getHeight() + centerDrawable.getIntrinsicHeight()) / 2f));
            }
            if(isPressed){
                centerDrawable.setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP);
            }else{
                centerDrawable.clearColorFilter();
            }
            centerDrawable.draw(canvas);
        }
        if (!TextUtils.isEmpty(centerText)) {
            if (isEnabled()) {
                mTextPaint.setAlpha(255);
            } else {
                mTextPaint.setAlpha(80);
            }
            if(isPressed){
                mTextPaint.setColor(0xffffffff);
            }else{
                mTextPaint.setColor(centerTextColor.getColorForState(isSelected() ? SELECTED_STATE_SET : UNSELECTED_STATE_SET, centerTextColor.getDefaultColor()));
            }
            float textWidth = mTextPaint.measureText(centerText);
            Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
            float textHeight = fontMetricsInt.descent - fontMetricsInt.ascent;
            String info = centerText;
            // measuredWidth 控件宽度   textWidth文本宽度
            // 超过可显示区域，显示省略号
            if (getWidth() < textWidth) {
                info = TextUtils.ellipsize(centerText, mTextPaint, getWidth(), TextUtils.TruncateAt.END).toString();
                textWidth = mTextPaint.measureText(info);
            }
            canvas.drawText(info, (getWidth() - textWidth) / 2f, getHeight() / 2f + textHeight / 2f - fontMetricsInt.descent, mTextPaint);
        }
    }

    private void drawCenter(Canvas canvas){
        float strokeHalfWidth = strokeWidth / 2f;
        mRectF.left = addWidth + strokeHalfWidth;
        mRectF.top = addWidth + strokeHalfWidth;
        mRectF.right = getWidth() - addWidth - strokeHalfWidth;
        mRectF.bottom = getHeight() - addWidth - strokeHalfWidth;
        drawStroke(canvas);
        mRectF.left = addWidth + strokeWidth;
        mRectF.top = addWidth + strokeWidth;
        mRectF.right = getWidth() - addWidth - strokeWidth;
        mRectF.bottom = getHeight() - addWidth - strokeWidth;
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(0);
        paint.setColor(deviceSolidBgColor);
        paint.setShadowLayer(shadowRadius1, 0, shadowDy1, 0x0f25334b);
        int r = radius - centerRadiusOffset;
        canvas.drawRoundRect(mRectF, r, r, paint);

        paint.setShadowLayer(shadowRadius2, 0, shadowDy2, 0x1425334b);
        canvas.drawRoundRect(mRectF, r, r, paint);

        paint.setShadowLayer(shadowRadius3, 0, shadowDy3, 0x0525334b);
        canvas.drawRoundRect(mRectF, r, r, paint);
        paint.clearShadowLayer();
        mPath.addRoundRect(mRectF, r, r, Path.Direction.CW);
    }

    private void drawStroke(Canvas canvas){
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(strokeColor);
        paint.clearShadowLayer();
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(strokeWidth);
//        if (strokeGradient == null) {
//            strokeGradient = new LinearGradient(mRectF.left, mRectF.top, mRectF.right, mRectF.bottom, startColor, endColor, Shader.TileMode.CLAMP);
//        }
//        paint.setShader(strokeGradient);
        canvas.drawRoundRect(mRectF, radius, radius, paint);
    }

    @Override
    public void setSelected(boolean selected) {
        super.setSelected(selected);
        if(centerDrawable != null){
            centerDrawable.setState(getDrawableState());
        }
        invalidate();
    }

    public void setCenterDrawable(int resId) {
        if(resId == 0){
            centerDrawable = null;
        }else{
            centerDrawable = getResources().getDrawable(resId);
        }
        invalidate();
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }
        RectF bounds;
        Region region;
        Region clickRegion;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                bounds = new RectF();
                region = new Region();
                clickRegion = new Region();
                mPath.computeBounds(bounds, true);
                region.set((int)bounds.left, (int)bounds.top, (int)bounds.right, (int)bounds.bottom);
                clickRegion.setPath(mPath, region);
                if(clickRegion.contains((int)event.getX(), (int)event.getY())){
                    isPressed = true;
                }else {
                    isPressed = false;
                    setPressed(false);
                    return true;
                }
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                bounds = new RectF();
                region = new Region();
                clickRegion = new Region();
                mPath.computeBounds(bounds, true);
                region.set((int)bounds.left, (int)bounds.top, (int)bounds.right, (int)bounds.bottom);
                clickRegion.setPath(mPath, region);
                if(!clickRegion.contains((int)event.getX(), (int)event.getY())){
                    isPressed = false;
                    setPressed(false);
                    invalidate();
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                isPressed = false;
                invalidate();
                break;
        }
        return super.onTouchEvent(event);
    }
}
